﻿#ifndef COLLISION_H
#define COLLISION_H
#include <cmath>
#include <algorithm>

//碰撞箱类型
enum class CollisionBoxType {
	Point,
	Rectangle,
	Circle
};

// 前置声明
class PointCollisionBox;
class RectangleCollisionBox;
class CircleCollisionBox;


// 碰撞箱抽象基类
class CollisionBox {
public:
	CollisionBox();
	CollisionBox(CollisionBoxType type);
	virtual ~CollisionBox() = default;

	// 获取碰撞箱类型
	CollisionBoxType getType() const;

	// 纯虚函数：判断与其他碰撞箱是否碰撞
	virtual bool checkCollision(const CollisionBox& other) const = 0;

	// 虚函数：与具体类型碰撞箱的碰撞检测
	virtual bool checkCollisionWithPoint(const PointCollisionBox& point) const = 0;
	virtual bool checkCollisionWithRectangle(const RectangleCollisionBox& rect) const = 0;
	virtual bool checkCollisionWithCircle(const CircleCollisionBox& circle) const = 0;

	// 静态方法，检测任意两个碰撞箱的碰撞
	static bool checkCollision(const CollisionBox& box1, const CollisionBox& box2);

private:
	CollisionBoxType type_;//碰撞箱类型
};

// 点碰撞箱
class PointCollisionBox : public CollisionBox {
public:
	PointCollisionBox();
	PointCollisionBox(float x, float y);

	float getX() const;
	float getY() const;

	bool setX(float x);
	bool setY(float y);

	// 判断与其他碰撞箱是否碰撞
	bool checkCollision(const CollisionBox& other) const override;

	bool checkCollisionWithPoint(const PointCollisionBox& point) const override;
	bool checkCollisionWithRectangle(const RectangleCollisionBox& rect) const override;
	bool checkCollisionWithCircle(const CircleCollisionBox& circle) const override;

private:
	float x_, y_;//点坐标
};

// 矩形碰撞箱
class RectangleCollisionBox : public CollisionBox {
public:
	RectangleCollisionBox();
	RectangleCollisionBox(float x, float y, float width, float height);

	float getX() const;
	float getY() const;
	float getWidth() const;
	float getLength() const;

	bool setX(float x);
	bool setY(float y);
	bool setWidth(float width);
	bool setLength(float length);

	// 判断与其他碰撞箱是否碰撞
	bool checkCollision(const CollisionBox& other) const override;

	bool checkCollisionWithPoint(const PointCollisionBox& point) const override;
	bool checkCollisionWithRectangle(const RectangleCollisionBox& rect) const override;
	bool checkCollisionWithCircle(const CircleCollisionBox& circle) const override;

private:
	float x_, y_;       // 矩形左上角坐标
	float width_, length_;
};

// 圆形碰撞箱
class CircleCollisionBox : public CollisionBox {
public:

	CircleCollisionBox();
	CircleCollisionBox(float x, float y, float radius);

	float getX() const;
	float getY() const;
	float getRadius() const;

	bool setX(float x);
	bool setY(float y);
	bool setRadius(float radius);

	// 判断与其他碰撞箱是否碰撞
	bool checkCollision(const CollisionBox& other) const override;

	bool checkCollisionWithPoint(const PointCollisionBox& point) const override;
	bool checkCollisionWithRectangle(const RectangleCollisionBox& rect) const override;
	bool checkCollisionWithCircle(const CircleCollisionBox& circle) const override;

private:
	float x_, y_;  // 圆心坐标
	float radius_; // 圆形半径
};


#endif

